package com.sys.basics.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sys.basics.config.constant.ScheduleConstant;
import com.sys.basics.utils.YmlUtils;
import com.sys.basics.utils.quartz.ScheduleUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import com.sys.basics.entity.SysScheduleJob;
import com.sys.basics.dao.SysScheduleJobDao;
import com.sys.basics.service.SysScheduleJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author: ares
 * @date: 2021-10-29
 * @description: 定时任务表 服务实现类
 */
@Slf4j
@Service
public class SysScheduleJobServiceImpl extends ServiceImpl<SysScheduleJobDao, SysScheduleJob> implements SysScheduleJobService {

    @Autowired
	SysScheduleJobDao sysScheduleJobDao;

    @Autowired
    private Scheduler scheduler;

    @Override
    public List<Object> getSupportiveJobTasks() {
        Object supportiveJob = YmlUtils.getJson().get("supportiveJob");
        String jsonStr = JSONObject.toJSON(supportiveJob).toString();
        JSONArray tasks = JSONObject.parseObject(jsonStr).getJSONArray("tasks");
        return  tasks;
    }

    @Override
    public boolean createJob(SysScheduleJob sysScheduleJob) {
        int insertedNum = sysScheduleJobDao.insert(sysScheduleJob);
        try {
            ScheduleUtils.createScheduleJob(scheduler, sysScheduleJob);
        }catch (SchedulerException e){
            throw new RuntimeException("添加定时任务失败", e);
        }
        return insertedNum > 0;
    }

    @Override
    public boolean updateJob(SysScheduleJob sysScheduleJob) {
        int updatedNum = sysScheduleJobDao.updateById(sysScheduleJob);
        try {
            ScheduleUtils.updateScheduleJob(scheduler, sysScheduleJob);
        }catch (SchedulerException e){
            throw new RuntimeException("更新定时任务失败", e);
        }
        return updatedNum > 0;
    }

    @Override
    public Map<String, Object> batchRun(List<Long> scheduleJobIds) {
        HashMap<String, Object> hashMap = new HashMap<>();
        Integer successNum = 0;
        ArrayList<String> errorMsg = new ArrayList<>();
        for (Long jobId : scheduleJobIds) {
            SysScheduleJob job = sysScheduleJobDao.selectById(jobId);
            if (ObjectUtil.isNull(job)) {
                continue;
            }
            if(job.getStatus().equals(ScheduleConstant.ScheduleStatus.RUNNING.getStatus())){
                continue;
            }
            try {
                ScheduleUtils.runJob(scheduler, job);
                successNum++;
            } catch (SchedulerException e) {
                String msg = job.getBeanName() + " " + job.getRemark();
                errorMsg.add(msg);
                log.error(">>>定时任务执行出错, {}<<<", msg, e);
            }
        }
        hashMap.put("successNum", successNum);
        hashMap.put("errorMsg", errorMsg);
        return hashMap;
    }

    @Override
    public Map<String, Object> batchPause(List<Long> scheduleJobIds) {
        HashMap<String, Object> hashMap = new HashMap<>();
        Integer successNum = 0;
        ArrayList<String> errorMsg = new ArrayList<>();
        for (Long jobId : scheduleJobIds) {
            SysScheduleJob job = sysScheduleJobDao.selectById(jobId);
            if (ObjectUtil.isNull(job)) {
                continue;
            }
            if(job.getStatus().equals(ScheduleConstant.ScheduleStatus.PAUSE.getStatus())){
                continue;
            }
            try {
                ScheduleUtils.pauseJob(scheduler, jobId);
                job.setStatus(ScheduleConstant.ScheduleStatus.PAUSE.getStatus());
                sysScheduleJobDao.updateById(job);
                successNum++;
            } catch (SchedulerException e) {
                String msg = job.getBeanName() + " " + job.getRemark();
                errorMsg.add(msg);
                log.error(">>>定时任务暂停出错, {}<<<", msg, e);
            }
        }
        hashMap.put("successNum", successNum);
        hashMap.put("errorMsg", errorMsg);
        return hashMap;
    }

    @Override
    public Map<String, Object> batchResume(List<Long> scheduleJobIds) {
        HashMap<String, Object> hashMap = new HashMap<>();
        Integer successNum = 0;
        ArrayList<String> errorMsg = new ArrayList<>();
        for (Long jobId : scheduleJobIds) {
            SysScheduleJob job = sysScheduleJobDao.selectById(jobId);
            if (ObjectUtil.isNull(job)) {
                continue;
            }
            if(job.getStatus().equals(ScheduleConstant.ScheduleStatus.RUNNING.getStatus())){
                continue;
            }
            try {
                ScheduleUtils.resumeJob(scheduler, jobId);
                job.setStatus(ScheduleConstant.ScheduleStatus.RUNNING.getStatus());
                sysScheduleJobDao.updateById(job);
                successNum++;
            } catch (SchedulerException e) {
                String msg = job.getBeanName() + " " + job.getRemark();
                errorMsg.add(msg);
                log.error(">>>定时任务执行出错, {}<<<", msg, e);
            }
        }
        hashMap.put("successNum", successNum);
        hashMap.put("errorMsg", errorMsg);
        return hashMap;
    }

    @Override
    public Map<String, Object> batchRemove(List<Long> scheduleJobIds) {
        HashMap<String, Object> hashMap = new HashMap<>();
        Integer successNum = 0;
        ArrayList<String> errorMsg = new ArrayList<>();
        for (Long jobId : scheduleJobIds) {
            SysScheduleJob job = sysScheduleJobDao.selectById(jobId);
            if (ObjectUtil.isNull(job)) {
                continue;
            }
            try {
                sysScheduleJobDao.deleteById(jobId);
                ScheduleUtils.deleteJob(scheduler, jobId);
                successNum++;
            } catch (SchedulerException e) {
                String msg = job.getBeanName() + " " + job.getRemark();
                errorMsg.add(msg);
                log.error(">>>定时任务执行出错, {}<<<", msg, e);
            }
        }
        hashMap.put("successNum", successNum);
        hashMap.put("errorMsg", errorMsg);
        return hashMap;
    }
}
